package com.laboratory.miniooperate.service.impl;

import com.laboratory.miniooperate.domain.UploadResult;
import com.laboratory.miniooperate.properties.MinioProperties;
import com.laboratory.miniooperate.service.UploadService;
import com.laboratory.miniooperate.util.MinioUtil;
import io.minio.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@Service
@RequiredArgsConstructor
public class UploadServiceImpl implements UploadService {

    private final MinioClient minioClient;

    private final MinioProperties minioProperties;

    /**
     * 上传文件
     *
     * @param file 文件
     * @return 上传结果
     */
    @Override
    public UploadResult uploadFile(MultipartFile file) {
        try {
            String endpoint = minioProperties.getEndpoint();
            String originalName = file.getOriginalFilename();
            log.info("开始上传文件:{}", originalName);
            String contentType = MinioUtil.pickContentType(file.getContentType(), originalName);
            String bucketName = minioProperties.getBucketName();
            String objectName = MinioUtil.buildObjectName(originalName);
            String publicUrl = endpoint + "/" + bucketName + "/" + objectName;
            ObjectWriteResponse objectWriteResponse = minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(contentType)
                            .stream(file.getInputStream(), file.getSize(), -1)
                            .build()
            );
            return new UploadResult(
                    originalName,
                    contentType,
                    bucketName,
                    objectName,
                    file.getSize(),
                    publicUrl,
                    objectWriteResponse.etag()
            );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除文件
     *
     * @param objectName
     * @return
     */
    @Override
    public Boolean deletedFile(String objectName) {
        try {
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(minioProperties.getBucketName())
                            .object(objectName)
                            .build()
            );
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 预览与下载文件
     * isDownload：true为下载，false为预览
     *
     * @param objectName
     * @return
     */
    @Override
    public ResponseEntity<InputStreamResource> downloadFile(String objectName, Boolean isDownload) {
        try {
            StatObjectResponse statObjectResponse = statFile(objectName);
            if (statObjectResponse == null) {
                throw new RuntimeException("文件不存在");
            }
            GetObjectResponse getObjectResponse = minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(minioProperties.getBucketName())
                            .object(objectName)
                            .build()
            );
            String contentType = MinioUtil.pickContentType(statObjectResponse.contentType(), objectName);
            long fileSize = statObjectResponse.size();
            String fileName = MinioUtil.fileName(objectName);
            if (isDownload) {
                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
                        .contentLength(fileSize)
                        .body(new InputStreamResource(getObjectResponse));
            } else {
                return ResponseEntity.ok()
                        .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + fileName + "\"")
                        .contentType(MediaType.parseMediaType(contentType))
                        .contentLength(fileSize)
                        .body(new InputStreamResource(getObjectResponse));
            }
        } catch (Exception e) {
            throw new RuntimeException("显示或下载失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取文件信息
     *
     * @param objectName
     * @return
     */
    private StatObjectResponse statFile(String objectName) {
        try {
            return minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(minioProperties.getBucketName())
                            .object(objectName)
                            .build()
            );
        } catch (Exception e) {
            return null;
        }
    }

}
